package tools.packet;

import client.BuddyList;
import client.MapleCharacter;
import client.MapleClient;
import client.MapleCoolDownValueHolder;
import client.MapleEquipStat;
import client.MapleQuestStatus;
import client.MapleTrait;
import client.MapleTrait.MapleTraitType;
import client.MonsterBook;
import client.PartTimeJob;
import client.PlayerStats;
import client.Skill;
import client.SkillEntry;
import client.SkillFactory;
import client.inventory.Equip;
import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.MaplePet;
import client.inventory.MapleRing;
import constants.GameConstants;
import database.DatabaseConnection;
import handling.Buffstat;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import javax.swing.text.html.CSS;
import server.MapleCarnivalChallenge;
import server.MapleItemInformationProvider;
import server.MapleShop;
import server.MapleShopItem;
import server.ServerProperties;
import server.movement.LifeMovementFragment;
import server.quest.MapleQuest;
import server.shops.AbstractPlayerStore;
import server.shops.IMaplePlayerShop;
import tools.BitTools;
import tools.DateUtil;
import tools.FileoutputUtil;
import tools.HexTool;
import tools.Pair;
import tools.StringUtil;
import tools.Triple;
import tools.data.MaplePacketLittleEndianWriter;

public class PacketHelper {

    public static long FT_UT_OFFSET = 116444592000000000L;
    public static long MAX_TIME = 150842304000000000L;
    public static long ZERO_TIME = 94354848000000000L;
    public static long PERMANENT = 150841440000000000L;
    public static long RENWU_TIME = 814568955L;
    public static int 完成任务时间 = 1300000000;

    public static long getKoreanTimestamp(long realTimestamp) {
        return getTime(realTimestamp);
    }

    public static long getTime(long realTimestamp) {
        if (realTimestamp == -1L) {
            return MAX_TIME;
        }
        if (realTimestamp == -2L) {
            return ZERO_TIME;
        }
        if (realTimestamp == -3L) {
            return PERMANENT;
        }
        if (realTimestamp == -5L) {
            return realTimestamp * 10000L - RENWU_TIME;
        }

        return realTimestamp * 10000L + FT_UT_OFFSET;
    }

    public static int 取得任务完成时间(int time) {
        return time + 完成任务时间;
    }

    public static long getFileTimestamp(long timeStampinMillis, boolean roundToMinutes) {
        if (SimpleTimeZone.getDefault().inDaylightTime(new Date())) {
            timeStampinMillis -= 3600000L;
        }
        long time;
        //long time;
        if (roundToMinutes) {
            time = timeStampinMillis / 1000L / 60L * 600000000L;
        } else {
            time = timeStampinMillis * 10000L;
        }
        return time + FT_UT_OFFSET;
    }

    public static void addQuestInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        List<MapleQuestStatus> started = chr.getStartedQuests();

        mplew.write(1);
        mplew.writeShort(started.size());
        for (MapleQuestStatus q : started) {
            mplew.writeShort(q.getQuest().getId());
            if (q.hasMobKills()) {
                StringBuilder sb = new StringBuilder();
                for (Iterator i$ = q.getMobKills().values().iterator(); i$.hasNext();) {
                    int kills = ((Integer) i$.next()).intValue();
                    sb.append(StringUtil.getLeftPaddedStr(String.valueOf(kills), '0', 3));
                }
                mplew.writeMapleAsciiString(sb.toString());
            } else {
                mplew.writeMapleAsciiString(q.getCustomData() == null ? "" : q.getCustomData());
            }

        }

        mplew.write(1);
        List<MapleQuestStatus> completed = chr.getCompletedQuests();
        mplew.writeShort(completed.size());
        for (MapleQuestStatus q : completed) {
            mplew.writeShort(q.getQuest().getId());
            mplew.writeInt(q.取得任务完成时间());
        }
    }

    public static void addSkillInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        final Map<Skill, SkillEntry> skills = chr.getSkills();
        mplew.write(1);
        mplew.writeShort(skills.size());
        for (Map.Entry skill : skills.entrySet()) {
            mplew.writeInt(((Skill) skill.getKey()).getId());
            if ((((Skill) skill.getKey()).getId() == 80000000) || (((Skill) skill.getKey()).getId() == 80000001) || (((Skill) skill.getKey()).getId() == 80001040)) {
                mplew.writeInt(((SkillEntry) skill.getValue()).teachId);
            } else if ((((Skill) skill.getKey()).getId() == 110) || (((Skill) skill.getKey()).getId() == 20021110) || (((Skill) skill.getKey()).getId() == 30010112)) {
                mplew.writeInt(((SkillEntry) skill.getValue()).teachId > 0 ? ((SkillEntry) skill.getValue()).teachId : ((SkillEntry) skill.getValue()).skillevel);
            } else {
                mplew.writeInt(((SkillEntry) skill.getValue()).skillevel);
            }
            addExpirationTime(mplew, ((SkillEntry) skill.getValue()).expiration);
            byte masterlevel = 0;
            if ((((Skill) skill.getKey()).isFourthJob()) || (((Skill) skill.getKey()).is神之子技能写入_MAXLEVEL()) || (((Skill) skill.getKey()).is冒险家超级技能()) || (GameConstants.is超级技能(chr.getJob(), ((Skill) skill.getKey()).getId())) || (GameConstants.有最大等级的特殊技能(((Skill) skill.getKey()).getId()))) {
                masterlevel = ((SkillEntry) skill.getValue()).masterlevel;
                if (masterlevel <= 0) {
                    Skill skil = SkillFactory.getSkill(((Skill) skill.getKey()).getId());
                    masterlevel = (byte) skil.getMaxLevel();
                    if (masterlevel <= 0) {
                        if (GameConstants.is超级技能(chr.getJob(), ((Skill) skill.getKey()).getId())) {
                            masterlevel = 1;
                        } else {
                            masterlevel = 5;
                        }
                    }
                    chr.changeSkillLevel_Skip(skil, ((SkillEntry) skill.getValue()).skillevel, masterlevel);
                }
                mplew.writeInt(masterlevel);
            }
            if (((((SkillEntry) skill.getValue()).skillevel >= 5) && (chr.isGM()) && (ServerProperties.ShowPacket())) || (ServerProperties.IsLvkejian())) {
                String job = new StringBuilder().append("log\\职业技能数据_").append(MapleCarnivalChallenge.getJobNameById(chr.getJob())).append(".log").toString();
                FileoutputUtil.packetLog(job, new StringBuilder().append("玩家技能: ").append(((Skill) skill.getKey()).getId()).append(" 名字: ").append(SkillFactory.getSkillName(((Skill) skill.getKey()).getId())).append(" 技能等级: ").append(((SkillEntry) skill.getValue()).skillevel).append("/").append(((SkillEntry) skill.getValue()).masterlevel).append(" 是否写最大等级: ").append(((Skill) skill.getKey()).isFourthJob()).append(" masterlevel = ").append(masterlevel).toString());
            }
        }
    }

    public static void addCoolDownInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        final List<MapleCoolDownValueHolder> cd = chr.getCooldowns();
        mplew.writeShort(cd.size());
        for (MapleCoolDownValueHolder cooling : cd) {
            mplew.writeInt(cooling.skillId);
            int timeLeft = (int) (cooling.length + cooling.startTime - System.currentTimeMillis());
            mplew.writeInt(timeLeft / 1000);
        }
    }

    public static void addRocksInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        int[] mapz = chr.getRegRocks();
        for (int i = 0; i < 5; i++) {
            mplew.writeInt(mapz[i]);
        }
        int[] map = chr.getRocks();
        for (int i = 0; i < 10; i++) {
            mplew.writeInt(map[i]);
        }
        int[] maps = chr.getHyperRocks();
        for (int i = 0; i < 13; i++) {
            mplew.writeInt(maps[i]);
        }
    }

    public static void addRingInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.writeShort(0);

        Triple<List<MapleRing>, List<MapleRing>, List<MapleRing>> aRing = chr.getRings(true);
        List<MapleRing> cRing = aRing.getLeft();
        mplew.writeShort(cRing.size());
        for (MapleRing ring : cRing) {
            mplew.writeInt(ring.getPartnerChrId());
            mplew.writeAsciiString(ring.getPartnerName(), 13);
            mplew.writeLong(ring.getRingId());
            mplew.writeLong(ring.getPartnerRingId());
        }
        List<MapleRing> fRing = aRing.getMid();
        mplew.writeShort(fRing.size());
        for (MapleRing ring : fRing) {
            mplew.writeInt(ring.getPartnerChrId());
            mplew.writeAsciiString(ring.getPartnerName(), 13);
            mplew.writeLong(ring.getRingId());
            mplew.writeLong(ring.getPartnerRingId());
            mplew.writeInt(ring.getItemId());
        }
        List<MapleRing> mRing = aRing.getMid();
        mplew.writeShort(mRing.size());
        int marriageId = 30000;
        for (MapleRing ring : mRing) {
            mplew.writeInt(marriageId);
            mplew.writeInt(chr.getId());
            mplew.writeInt(ring.getPartnerChrId());
            mplew.writeShort(3);
            mplew.writeInt(ring.getItemId());
            mplew.writeInt(ring.getItemId());
            mplew.writeAsciiString(chr.getName(), 13);
            mplew.writeAsciiString(ring.getPartnerName(), 13);
        }
    }

    public static void addInventoryInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.writeLong(chr.getMeso());
        mplew.writeInt(chr.getId());
        mplew.writeInt(chr.getBeans());
        mplew.writeInt(chr.getCSPoints(2));
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(chr.getId());
        //  mplew.write(HexTool.getByteArrayFromHexString("85 52 B1"));

        for (int ii = 0; ii < 8; ii++) {
            mplew.writeInt(0);
        }

        mplew.write(0);    //我改的
        mplew.writeShort(0); //我改的

        mplew.write(chr.getInventory(MapleInventoryType.EQUIP).getSlotLimit());
        mplew.write(chr.getInventory(MapleInventoryType.USE).getSlotLimit());
        mplew.write(chr.getInventory(MapleInventoryType.SETUP).getSlotLimit());
        mplew.write(chr.getInventory(MapleInventoryType.ETC).getSlotLimit());
        mplew.write(chr.getInventory(MapleInventoryType.CASH).getSlotLimit());

        MapleQuestStatus stat = chr.getQuestNoAdd(MapleQuest.getInstance(122700));
        if ((stat != null) && (stat.getCustomData() != null) && (Long.parseLong(stat.getCustomData()) > System.currentTimeMillis())) {
            mplew.writeLong(getTime(Long.parseLong(stat.getCustomData())));
        } else {
            mplew.writeLong(getTime(-2L));
        }

        mplew.write(0); //我加的

        MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
        List<Item> equipped = iv.newList();
        Collections.sort(equipped);

        for (Item item : equipped) {
            if ((item.getPosition() < 0) && (item.getPosition() > -100)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -100) && (item.getPosition() > -1000)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        iv = chr.getInventory(MapleInventoryType.EQUIP);
        for (Item item : iv.list()) {
            addItemInfo(mplew, item, false, false, false, false, chr);
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -1000) && (item.getPosition() > -1100)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -1100) && (item.getPosition() > -1200)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -1200) && (item.getPosition() > -1300)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -5000) && (item.getPosition() > -5003)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() >= -136) && (item.getPosition() <= -120) && (item.getItemId() >= 1680000) && (item.getItemId() <= 1680057)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() <= -1500) && (item.getPosition() > -2000)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);

        mplew.writeShort(0);

        for (Item item : equipped) {
            if ((item.getPosition() >= -136) && (item.getPosition() <= -120) && (item.getItemId() >= 1680000) && (item.getItemId() <= 1680057)) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.writeShort(0);
        
        
        
        mplew.writeLong(0);

        iv = chr.getInventory(MapleInventoryType.USE);
        for (Item item : iv.list()) {
            addItemInfo(mplew, item, false, false, false, false, chr);
        }
        mplew.write(0);

        iv = chr.getInventory(MapleInventoryType.SETUP);
        for (Item item : iv.list()) {
            addItemInfo(mplew, item, false, false, false, false, chr);
        }
        mplew.write(0);

        iv = chr.getInventory(MapleInventoryType.ETC);
        for (Item item : iv.list()) {
            if (item.getPosition() < 100) {
                addItemInfo(mplew, item, false, false, false, false, chr);
            }
        }
        mplew.write(0);

        iv = chr.getInventory(MapleInventoryType.CASH);
        for (Item item : iv.list()) {
            addItemInfo(mplew, item, false, false, false, false, chr);
        }
        mplew.write(0);

        mplew.writeLong(0L);

        for (int i = 0; i < chr.getExtendedSlots().size(); i++) {
            mplew.writeInt(i);
            mplew.writeInt(chr.getExtendedSlot(i));
            for (Item item : chr.getInventory(MapleInventoryType.ETC).list()) {
                if ((item.getPosition() > i * 100 + 100) && (item.getPosition() < i * 100 + 200)) {
                    addItemInfo(mplew, item, false, false, false, true, chr);
                }
            }

            mplew.writeInt(-1);
        }

        mplew.writeLong(0L);
        mplew.write(0);
    }

    public static void addCharStats(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.writeInt(chr.getId());
        mplew.writeAsciiString(chr.getName(), 13);
        mplew.write(GameConstants.is神之子(chr.getJob()) ? 0 : chr.getGender());
        mplew.write(chr.getSkinColor());
        mplew.writeInt(chr.getFace());
        mplew.writeInt(chr.getHair());

        mplew.write(chr.getLevel());
        mplew.writeShort(chr.getJob());
        chr.getStat().connectData(mplew, chr.getJob());//4个Short  4个Int
        mplew.writeShort(chr.getRemainingAp());

        addRemainingSp(mplew, chr);

        mplew.writeLong(chr.getExp());
        mplew.writeInt(chr.getFame());
        mplew.writeInt(chr.getGachExp());

        mplew.writeLong(0L);

        mplew.writeLong(DateUtil.getFileTimestamp(System.currentTimeMillis()));

        mplew.writeInt(chr.getMapId());

        mplew.write(chr.getInitialSpawnpoint());

        mplew.writeShort(chr.getSubcategory());

       
        if ((GameConstants.is恶魔猎手(chr.getJob())) || (GameConstants.is林之灵(chr.getJob())) || (GameConstants.is尖兵(chr.getJob())) || (GameConstants.is恶魔复仇者(chr.getJob()))) {
            mplew.writeInt(chr.getFaceMarking());
        }


        mplew.write(chr.getFatigue());

        mplew.writeInt(DateUtil.getTime());//登陆还是注册时间?

        //这里是魅力，手技，感性什么的  6个int和6个short
        for (MapleTrait.MapleTraitType t : MapleTrait.MapleTraitType.values()) {    //这里是魅力，手技，感性什么的  4个int和4个short
            mplew.writeInt(chr.getTrait(t).getTotalExp());
        }

        for (MapleTrait.MapleTraitType t : MapleTrait.MapleTraitType.values()) {
            mplew.writeShort(0);
        }

        mplew.write(0);
        mplew.writeLong(getTime(-2L));

        mplew.writeInt(chr.getStat().pvpExp);
        mplew.write(chr.getStat().pvpRank);
        mplew.writeInt(chr.getBattlePoints());
        mplew.write(6);
        mplew.write(7);
        mplew.writeInt(0);
        //mplew.write(0);
        //mplew.writeLong(DateUtil.getFileTimestamp(System.currentTimeMillis()));
        // mplew.write(HexTool.getByteArrayFromHexString("3B 37 4F 01 00 40 E0 FD"));

       /* for (int i = 0; i < 10; i++) {
            mplew.writeLong(0L);
        }*/
        
        addPartTimeJob(mplew, MapleCharacter.getPartTime(chr.getId()));
        chr.getCharacterCard().connectData(mplew, chr);
        mplew.writeLong(DateUtil.getFileTimestamp(System.currentTimeMillis()));
        mplew.writeInt(DateUtil.getTime());
    }

    public static void addRemainingSp(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        if ((GameConstants.is神之子(chr.getJob())) || 
                ((GameConstants.is冒险家(chr.getJob())) && (!GameConstants.is龙的传人(chr.getJob()))) || 
                (GameConstants.is骑士团(chr.getJob())) || 
                (GameConstants.is尖兵(chr.getJob())) || 
                (GameConstants.is恶魔复仇者(chr.getJob())) || 
                (GameConstants.is狂龙(chr.getJob())) || 
                (GameConstants.is萌天使(chr.getJob())) || 
                (GameConstants.is夜光(chr.getJob())) || 
                (GameConstants.is米哈尔(chr.getJob())) || 
                (GameConstants.is龙神(chr.getJob())) || 
                (GameConstants.is反抗者(chr.getJob())) || 
                (GameConstants.is双弩精灵(chr.getJob())) || 
                (GameConstants.is恶魔猎手(chr.getJob())) || 
                (GameConstants.is幻影(chr.getJob()))|| 
                (GameConstants.is隐月(chr.getJob()))) {
            int size = chr.getRemainingSpSize();
            mplew.write(size);
            for (int i = 0; i < chr.getRemainingSps().length; i++) {
                if (chr.getRemainingSp(i) > 0) {
                    mplew.write(i + 1);
                    mplew.writeInt(chr.getRemainingSp(i));
                }
            }
        } else {
            mplew.writeShort(chr.getRemainingSp());
        }
    }

    public static void addCharLook(MaplePacketLittleEndianWriter mplew, MapleCharacter chr, boolean mega, boolean 刷新神之子外观, boolean 是否加载另一个神之子) {
        addCharLook(mplew, chr, mega, true, 刷新神之子外观, 是否加载另一个神之子);
    }

    public static void addCharLook(MaplePacketLittleEndianWriter mplew, MapleCharacter chr, boolean mega, boolean channelserver, boolean 刷新神之子外观, boolean 是否加载另一个神之子) {
        boolean 神之子_贝塔在前 = false;
        boolean is神之子 = false;
        if (GameConstants.is神之子(chr.getJob())) {
            is神之子 = true;
        }
        if ((chr.get神之子_生成角色性别() == 1) && (is神之子) && (channelserver == true)) {
            神之子_贝塔在前 = true;
        }
        mplew.write(chr.getGender());
        mplew.write(chr.getSkinColor());
        mplew.writeInt(神之子_贝塔在前 ? chr.getFace1() : chr.getFace());
        mplew.writeInt(chr.getJob());
        mplew.write(mega ? 1 : 0);
        mplew.writeInt(神之子_贝塔在前 ? chr.getHair1() : chr.getHair());

        final Map<Byte, Integer> myEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> maskedEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> totemEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> 神之子_贝塔_myEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> 神之子_贝塔_maskedEquip = new LinkedHashMap<Byte, Integer>();
        MapleInventory equip = chr.getInventory(MapleInventoryType.EQUIPPED);

        for (Item item : equip.newList()) {
            if ((item.getPosition() >= -128) || ((item.getPosition() >= -1510) && (item.getPosition() <= -1500) && (!is神之子))) {
                byte pos = (byte) (item.getPosition() * -1);

                if ((is神之子) && (神之子_贝塔在前) && (item.getPosition() * -1 >= 1500)) {
                    byte poss = (byte) ((item.getPosition() + 1400) * -1);
                    byte poa = GameConstants.get神之子_贝塔_点装位点反馈(poss);

                    if ((poa < 100) && (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) == null)) {
                        神之子_贝塔_myEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    } else if (((poa > 100) || (poa == -128)) && (poa != 111)) {
                        poa = (byte) (poa == -128 ? 28 : poa - 100);
                        if (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) != null) {
                            神之子_贝塔_maskedEquip.put(Byte.valueOf(poa), 神之子_贝塔_myEquip.get(Byte.valueOf(poa)));
                        }
                        神之子_贝塔_myEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    } else if (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) != null) {
                        神之子_贝塔_maskedEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    }
                }
                if ((is神之子) && (神之子_贝塔在前) && (!GameConstants.is神之子_点装位点(pos))) {
                    if ((pos < 100) && (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) == null)) {
                        神之子_贝塔_myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    } else if (((pos > 100) || (pos == -128)) && (pos != 111)) {
                        pos = (byte) (pos == -128 ? 28 : pos - 100);
                        if (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) != null) {
                            神之子_贝塔_maskedEquip.put(Byte.valueOf(pos), 神之子_贝塔_myEquip.get(Byte.valueOf(pos)));
                        }
                        神之子_贝塔_myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    } else if (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) != null) {
                        神之子_贝塔_maskedEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    }
                } else if ((pos < 100) && (myEquip.get(Byte.valueOf(pos)) == null)) {
                    myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                } else if (((pos > 100) || (pos == -128)) && (pos != 111)) {
                    pos = (byte) (pos == -128 ? 28 : pos - 100);
                    if (myEquip.get(Byte.valueOf(pos)) != null) {
                        maskedEquip.put(Byte.valueOf(pos), myEquip.get(Byte.valueOf(pos)));
                    }
                    myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                } else if (myEquip.get(Byte.valueOf(pos)) != null) {
                    maskedEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                }
            }
        }

        for (Map.Entry entry : 神之子_贝塔在前 ? 神之子_贝塔_myEquip.entrySet() : myEquip.entrySet()) {
            if (GameConstants.is神之子(chr.getJob())) {
                if ((((Byte) entry.getKey()).byteValue() != 10) && (!神之子_贝塔在前)) {
                    mplew.write(((Byte) entry.getKey()).byteValue());
                    mplew.writeInt(((Integer) entry.getValue()).intValue());
                }
                if ((((Byte) entry.getKey()).byteValue() != 11) && (神之子_贝塔在前 == true)) {
                    mplew.write(((Byte) entry.getKey()).byteValue() == 10 ? 11 : ((Byte) entry.getKey()).byteValue());
                    mplew.writeInt(((Integer) entry.getValue()).intValue());
                }
            } else {
                mplew.write(((Byte) entry.getKey()).byteValue());
                mplew.writeInt(((Integer) entry.getValue()).intValue());
            }
        }
        mplew.write(0xFF);

        for (Map.Entry entry : 神之子_贝塔在前 ? 神之子_贝塔_maskedEquip.entrySet() : maskedEquip.entrySet()) {
            mplew.write(((Byte) entry.getKey()).byteValue());
            mplew.writeInt(((Integer) entry.getValue()).intValue());
        }
        mplew.write(0xFF);

        for (Map.Entry entry : totemEquip.entrySet()) {
            mplew.write(((Byte) entry.getKey()).byteValue());
            mplew.writeInt(((Integer) entry.getValue()).intValue());
        }
        mplew.write(0xFF);

        Item cWeapon = equip.getItem((short) -111);

        Item aWeapon = equip.getItem((short) (神之子_贝塔在前 ? -10 : -11));

        Item bWeapon = equip.getItem((short) -10);

        mplew.writeInt(cWeapon != null ? cWeapon.getItemId() : 0);

        mplew.writeInt(aWeapon != null ? aWeapon.getItemId() : 0);
        mplew.writeInt((bWeapon != null) && (!is神之子) ? bWeapon.getItemId() : 0);
        
        if (GameConstants.is双弩精灵(chr.getJob())) {
            mplew.write(1); //双弩精灵的耳朵
        } else {
            mplew.write(0);
        }

        //mplew.write(chr.getElfEar());

        for (int i = 0; i < 3; i++) {
            if (channelserver) {
                mplew.writeInt(chr.getPet(i) != null ? chr.getPet(i).getPetItemId() : 0);
            } else {
                mplew.writeInt(0);
            }
        }

        if ((GameConstants.is恶魔猎手(chr.getJob())) || (GameConstants.is林之灵(chr.getJob())) || (GameConstants.is尖兵(chr.getJob())) || (GameConstants.is恶魔复仇者(chr.getJob()))) {
            mplew.writeInt(chr.getFaceMarking());
        }
        if ((GameConstants.is林之灵(chr.getJob()))) {
            mplew.write(1);
            mplew.writeInt(chr.getEars());
            //mplew.writeInt(5010116);
            mplew.write(1);
            mplew.writeInt(chr.getTail());
            //mplew.writeInt(5010119);
        }


        if (is神之子 == true) {
            if (刷新神之子外观) {
                mplew.writeInt(0);
            }
            if (是否加载另一个神之子 == true) {
                mplew.write(神之子_贝塔在前 ? 1 : 0);
                addCharLook神之子(mplew, chr, mega, channelserver, 神之子_贝塔在前);
            }
            mplew.write((channelserver) && (!刷新神之子外观) ? 0 : 1);
        }
    }

    public static void addCharLook神之子(MaplePacketLittleEndianWriter mplew, MapleCharacter chr, boolean mega, boolean channelserver, boolean 神之子_贝塔在前) {
        mplew.write(神之子_贝塔在前 ? 0 : 1);
        mplew.write(chr.getSkinColor());
        mplew.writeInt(神之子_贝塔在前 ? chr.getFace() : chr.getFace1());
        mplew.writeInt(chr.getJob());
        mplew.write(mega ? 1 : 0);
        mplew.writeInt(神之子_贝塔在前 ? chr.getHair() : chr.getHair1());

        final Map<Byte, Integer> myEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> maskedEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> totemEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> 神之子_贝塔_myEquip = new LinkedHashMap<Byte, Integer>();
        final Map<Byte, Integer> 神之子_贝塔_maskedEquip = new LinkedHashMap<Byte, Integer>();
        MapleInventory equip = chr.getInventory(MapleInventoryType.EQUIPPED);

        for (Item item : equip.newList()) {
            if ((item.getPosition() >= -128) || ((item.getPosition() >= -1510) && (item.getPosition() <= -1500))) {
                byte pos = (byte) (item.getPosition() * -1);

                if ((!神之子_贝塔在前) && (item.getPosition() * -1 >= 1500)) {
                    byte poss = (byte) ((item.getPosition() + 1400) * -1);
                    byte poa = GameConstants.get神之子_贝塔_点装位点反馈(poss);

                    if ((poa < 100) && (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) == null)) {
                        神之子_贝塔_myEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    } else if (((poa > 100) || (poa == -128)) && (poa != 111)) {
                        poa = (byte) (poa == -128 ? 28 : poa - 100);
                        if (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) != null) {
                            神之子_贝塔_maskedEquip.put(Byte.valueOf(poa), 神之子_贝塔_myEquip.get(Byte.valueOf(poa)));
                        }
                        神之子_贝塔_myEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    } else if (神之子_贝塔_myEquip.get(Byte.valueOf(poa)) != null) {
                        神之子_贝塔_maskedEquip.put(Byte.valueOf(poa), Integer.valueOf(item.getItemId()));
                    }
                }
                if ((!神之子_贝塔在前) && (!GameConstants.is神之子_点装位点(pos))) {
                    if ((pos < 100) && (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) == null)) {
                        神之子_贝塔_myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    } else if (((pos > 100) || (pos == -128)) && (pos != 111)) {
                        pos = (byte) (pos == -128 ? 28 : pos - 100);
                        if (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) != null) {
                            神之子_贝塔_maskedEquip.put(Byte.valueOf(pos), 神之子_贝塔_myEquip.get(Byte.valueOf(pos)));
                        }
                        神之子_贝塔_myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    } else if (神之子_贝塔_myEquip.get(Byte.valueOf(pos)) != null) {
                        神之子_贝塔_maskedEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                    }
                } else if ((pos < 100) && (myEquip.get(Byte.valueOf(pos)) == null)) {
                    myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                } else if (((pos > 100) || (pos == -128)) && (pos != 111)) {
                    pos = (byte) (pos == -128 ? 28 : pos - 100);
                    if (myEquip.get(Byte.valueOf(pos)) != null) {
                        maskedEquip.put(Byte.valueOf(pos), myEquip.get(Byte.valueOf(pos)));
                    }
                    myEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                } else if (myEquip.get(Byte.valueOf(pos)) != null) {
                    maskedEquip.put(Byte.valueOf(pos), Integer.valueOf(item.getItemId()));
                }
            }
        }

        for (Map.Entry entry : !神之子_贝塔在前 ? 神之子_贝塔_myEquip.entrySet() : myEquip.entrySet()) {
            if ((((Byte) entry.getKey()).byteValue() != 11) && (!神之子_贝塔在前)) {
                mplew.write(((Byte) entry.getKey()).byteValue() == 10 ? 11 : ((Byte) entry.getKey()).byteValue());
                mplew.writeInt(((Integer) entry.getValue()).intValue());
            } else if ((((Byte) entry.getKey()).byteValue() != 10) && (神之子_贝塔在前 == true)) {
                mplew.write(((Byte) entry.getKey()).byteValue());
                mplew.writeInt(((Integer) entry.getValue()).intValue());
            }
        }

        mplew.write(255);

        for (Map.Entry entry : !神之子_贝塔在前 ? 神之子_贝塔_maskedEquip.entrySet() : maskedEquip.entrySet()) {
            mplew.write(((Byte) entry.getKey()).byteValue());
            mplew.writeInt(((Integer) entry.getValue()).intValue());
        }
        mplew.write(255);

        for (Map.Entry entry : totemEquip.entrySet()) {
            mplew.write(((Byte) entry.getKey()).byteValue());
            mplew.writeInt(((Integer) entry.getValue()).intValue());
        }
        mplew.write(255);

        Item cWeapon = equip.getItem((short) (!神之子_贝塔在前 ? -1507 : -111));

        Item aWeapon = equip.getItem((short) -11);
        Item bWeapon = equip.getItem((short) (神之子_贝塔在前 ? -11 : -10));

        mplew.writeInt(cWeapon != null ? cWeapon.getItemId() : 0);
        mplew.writeInt(bWeapon != null ? bWeapon.getItemId() : 0);
        mplew.writeInt(aWeapon != null ? 0 : 0);

        mplew.write(chr.getElfEar());

        for (int i = 0; i < 3; i++) {
            if (channelserver) {
                mplew.writeInt(chr.getPet(i) != null ? chr.getPet(i).getPetItemId() : 0);
            } else {
                mplew.writeInt(0);
            }
        }
    }

    public static void addExpirationTime(MaplePacketLittleEndianWriter mplew, long time) {
        mplew.writeLong(getTime(time));
    }

    public static void addItemInfo(MaplePacketLittleEndianWriter mplew, Item item, boolean zeroPosition, boolean leaveOut) {
        addItemInfo(mplew, item, zeroPosition, leaveOut, false, false, null);
    }

    public static void addItemInfo(MaplePacketLittleEndianWriter mplew, Item item, boolean zeroPosition, boolean leaveOut, boolean trade) {
        addItemInfo(mplew, item, zeroPosition, leaveOut, trade, false, null);
    }

    public static void addItemInfo(MaplePacketLittleEndianWriter mplew, Item item, boolean zeroPosition, boolean leaveOut, boolean trade, boolean bagSlot, MapleCharacter chr) {
        short pos = item.getPosition();    //这里只有个short是装备窗口的位置 武器是0B 00
        if (zeroPosition) {
            if (!leaveOut) {
                mplew.write(0);
            }
        } else {
            if (pos <= -1) {
                pos = (short) (pos * -1);
                if ((pos > 100) && (pos < 1000)) {
                    pos = (short) (pos - 100);
                }
            }
            if (bagSlot) {
                mplew.writeInt(pos % 100 - 1);
            } else if ((!trade) && (item.getType() == 1)) {
                mplew.writeShort(pos);  
//01是帽子 04是耳环 05是衣服 06应该是裤子 07是鞋子 08是手套
//09是披风 0A是武器 0B是武器 0C是戒指 0D是戒指 0F是戒指 10是戒指 11是吊坠 1A是奖章 1D是腰带 1E是护肩
            } else {
                mplew.write(pos);
            }
        }

        mplew.write(item.getPet() != null ? 3 : item.getType());  //物品的type下面有判断

        mplew.writeInt(item.getItemId());   //物品代码

        boolean hasUniqueId = (item.getUniqueId() > 0) && (!GameConstants.is结婚戒指(item.getItemId())) && (item.getItemId() / 10000 != 166);

        mplew.write(hasUniqueId ? 1 : 0);  //结婚了没有

        if (hasUniqueId) {
            mplew.writeLong(item.getUniqueId());
        }
        if (item.getPet() != null) {
            addPetItemInfo(mplew, item, item.getPet(), true);
        } else {
            addExpirationTime(mplew, item.getExpiration()); // 物品过期时间00 80 05 BB 46 E6 17 02


            //如果角色=没有  就写4个FF也就是-1   有的话就判断chr.getExtendedSlots().indexOf(Integer.valueOf(item.getItemId())));
            mplew.writeInt(chr == null ? -1 : chr.getExtendedSlots().indexOf(Integer.valueOf(item.getItemId())));


            if (item.getType() == 1) {  //如果上面获取物品类型是1的话就是装备，然后开始判断
                Equip equip = (Equip) item;

                walkEquipState(mplew, equip);  //转到装备属性那里去  首先一个Int 然后是可升级次数，然后是属性（从上往下，有几个属性就有几个short）

                mplew.writeInt(4);
                mplew.write(-1);

                mplew.writeMapleAsciiString(equip.getOwner()); //应该是制造者的名字 

                mplew.write(equip.getState());
                mplew.write(equip.getEnhance());

                mplew.writeShort(equip.getPotential1() <= 0 ? 0 : equip.getPotential1());  //潜能
                mplew.writeShort(equip.getPotential2() <= 0 ? 0 : equip.getPotential2());
                mplew.writeShort(equip.getPotential3() <= 0 ? 0 : equip.getPotential3());

                mplew.writeShort(equip.getPotential4() <= 0 ? 0 : equip.getPotential4());  //附加潜能
                mplew.writeShort(equip.getPotential5() <= 0 ? 0 : equip.getPotential5());
                mplew.writeShort(equip.getPotential6() <= 0 ? 0 : equip.getPotential6());

                mplew.writeShort(0);

                mplew.writeShort(equip.getSocketState());     //星岩状态 3:可插?  2:
                //下面是3个FF
                mplew.writeShort(equip.getSocket1() % 10000);// > 0 = 穿戴, 0 = 空, -1 = 没有
                mplew.writeShort(equip.getSocket2() % 10000);
                mplew.writeShort(equip.getSocket3() % 10000);


                if (!hasUniqueId) {
                    mplew.writeLong(equip.getInventoryId() <= 0L ? 219 : equip.getInventoryId());
                }

                mplew.writeLong(getTime(-2L));

                mplew.writeInt(-1);
                mplew.writeLong(0L);

                mplew.writeLong(getTime(-2L));
                mplew.writeLong(0L);

                mplew.writeShort(0);

                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? 0 : equip.getIsHunWuQi() == 1 ? equip.getHunSL() : 0);           //魂武器
                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? 0 : equip.getIsHunWuQi() == 1 ? equip.getHunSL() / 100 : 0);
                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? 0 : equip.getIsHunWuQi() == 1 ? equip.getHunSL() / 100 : 0);

                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? 0 : equip.getIsHunWuQi() == 1 ? equip.getHunWuQiType() : 0);

                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? equip.getIsHunWuQi() : 0);

                mplew.writeShort(GameConstants.isWeapon(item.getItemId()) ? equip.getPotential7() : equip.getPotential7() <= 0 ? 0 : 0);

                mplew.writeInt(GameConstants.isWeapon(item.getItemId()) ? equip.getMaxDamage() : 0);
            } else {
                mplew.writeShort(item.getQuantity()); //物品数量
                mplew.writeMapleAsciiString(item.getOwner());
                mplew.writeShort(item.getFlag());
                mplew.writeShort(0);//115+
                if ((GameConstants.isThrowingStar(item.getItemId())) || (GameConstants.isBullet(item.getItemId())) || (item.getItemId() / 10000 == 287)) {
                    mplew.writeLong(item.getInventoryId() <= 0L ? -1L : item.getInventoryId());
                }
            }
        }
    }

    public static void walkEquipState(MaplePacketLittleEndianWriter mplew, Equip equip) {
        List mes = new ArrayList();
        mes.add(new Pair(MapleEquipStat.USLOTS, equip.getUpgradeSlots() > 0 ? Byte.valueOf(equip.getUpgradeSlots()) : null));
        mes.add(new Pair(MapleEquipStat.LEVEL, equip.getLevel() > 0 ? Byte.valueOf(equip.getLevel()) : null));
        mes.add(new Pair(MapleEquipStat.STR, equip.getStr() > 0 ? Short.valueOf(equip.getStr()) : null));
        mes.add(new Pair(MapleEquipStat.DEX, equip.getDex() > 0 ? Short.valueOf(equip.getDex()) : null));
        mes.add(new Pair(MapleEquipStat.INT, equip.getInt() > 0 ? Short.valueOf(equip.getInt()) : null));
        mes.add(new Pair(MapleEquipStat.LUK, equip.getLuk() > 0 ? Short.valueOf(equip.getLuk()) : null));
        mes.add(new Pair(MapleEquipStat.HP, equip.getHp() > 0 ? Short.valueOf(equip.getHp()) : null));
        mes.add(new Pair(MapleEquipStat.MP, equip.getMp() > 0 ? Short.valueOf(equip.getMp()) : null));
        mes.add(new Pair(MapleEquipStat.WATK, equip.getWatk() > 0 ? Short.valueOf(equip.getWatk()) : null));
        mes.add(new Pair(MapleEquipStat.MATK, equip.getMatk() > 0 ? Short.valueOf(equip.getMatk()) : null));
        mes.add(new Pair(MapleEquipStat.WDEF, equip.getWdef() > 0 ? Short.valueOf(equip.getWdef()) : null));
        mes.add(new Pair(MapleEquipStat.MDEF, equip.getMdef() > 0 ? Short.valueOf(equip.getMdef()) : null));
        mes.add(new Pair(MapleEquipStat.ACC, equip.getAcc() > 0 ? Short.valueOf(equip.getAcc()) : null));
        mes.add(new Pair(MapleEquipStat.AVOID, equip.getAvoid() > 0 ? Short.valueOf(equip.getAvoid()) : null));
        mes.add(new Pair(MapleEquipStat.HANDS, equip.getHands() > 0 ? Short.valueOf(equip.getHands()) : null));
        mes.add(new Pair(MapleEquipStat.SPEED, equip.getSpeed() > 0 ? Short.valueOf(equip.getSpeed()) : null));
        mes.add(new Pair(MapleEquipStat.JUMP, equip.getJump() > 0 ? Short.valueOf(equip.getJump()) : null));
        mes.add(new Pair(MapleEquipStat.FLAG, equip.getFlag() > 0 ? Integer.valueOf(equip.getFlag()) : null));
        mes.add(new Pair(MapleEquipStat.ITEMSKILL, equip.getIncSkill() > 0 ? Integer.valueOf(1) : null));
        mes.add(new Pair(MapleEquipStat.ITEMLEVEL, equip.getEquipLevel() > 0 ? Integer.valueOf(Math.max(equip.getBaseLevel(), equip.getEquipLevel())) : null));

        int eep = equip.getExpPercentage();
        mes.add(new Pair(MapleEquipStat.ITEMEXP, eep > 0 ? Integer.valueOf(eep) : null));
        mes.add(new Pair(MapleEquipStat.DURABILITY, equip.getDurability() > 0 ? Integer.valueOf(equip.getDurability()) : null));
        mes.add(new Pair(MapleEquipStat.VICIOUS, equip.getViciousHammer() > 0 ? Byte.valueOf(equip.getViciousHammer()) : null));
        mes.add(new Pair(MapleEquipStat.PVP, equip.getPVPDamage() > 0 ? Short.valueOf(equip.getPVPDamage()) : null));
        mes.add(new Pair(MapleEquipStat.BOSS伤害, equip.getBOSSDamage() > 0 ? Integer.valueOf(equip.getBOSSDamage()) : null));
        mes.add(new Pair(MapleEquipStat.无视防御, equip.getWSMD() > 0 ? Integer.valueOf(equip.getWSMD()) : null));
        int pkstat = 0;
        for (int i = 0; i < mes.size(); i++) {
            if (((Pair) mes.get(i)).right != null) {
                pkstat += ((MapleEquipStat) ((Pair) mes.get(i)).left).getValue();
            }
        }

        mplew.writeInt(pkstat);

        for (int i = 0; i < mes.size(); i++) {
            if (((Pair) mes.get(i)).right != null) {
                switch (((MapleEquipStat) ((Pair) mes.get(i)).left)) {
                    case USLOTS://1
                    case LEVEL:
                    case ITEMSKILL:
                    case ITEMLEVEL:
                    case BOSS伤害:
                    case 无视防御:
                        mplew.write(Integer.parseInt(((Pair) mes.get(i)).right.toString()));
                        break;
                    case STR:
                    case DEX://5
                    case INT://6
                    case LUK:
                    case HP:
                    case MP:
                    case WATK:
                    case MATK:
                    case WDEF:
                    case MDEF:
                    case ACC:
                    case AVOID:
                    case HANDS:
                    case SPEED:
                    case JUMP:
                    case PVP:
                        mplew.writeShort(Integer.parseInt(((Pair) mes.get(i)).right.toString()));
                        break;
                    case FLAG://鐐硅涓撶敤锛佺┛鎴寸偣瑁呭彂閫佹暟鎹紒
                    case ITEMEXP:
                    case DURABILITY://鑰愪箙鍔?
                    case VICIOUS:
                        mplew.writeInt(Integer.parseInt(((Pair) mes.get(i)).right.toString()));
                }
            }
        }
    }

    public static void serializeMovementList(MaplePacketLittleEndianWriter lew, List<LifeMovementFragment> moves) {
        lew.write(moves.size());
        for (LifeMovementFragment move : moves) {
            move.serialize(lew);
        }
    }

    public static void addAnnounceBox(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        if ((chr.getPlayerShop() != null) && (chr.getPlayerShop().isOwner(chr)) && (chr.getPlayerShop().getShopType() != 1) && (chr.getPlayerShop().isAvailable())) {
            addInteraction(mplew, chr.getPlayerShop());
        } else {
            mplew.write(0);
        }
    }

    public static void addInteraction(MaplePacketLittleEndianWriter mplew, IMaplePlayerShop shop) {
        mplew.write(shop.getGameType());
        mplew.writeInt(((AbstractPlayerStore) shop).getObjectId());
        mplew.writeMapleAsciiString(shop.getDescription());
        if (shop.getShopType() != 1) {
            mplew.write(shop.getPassword().length() > 0 ? 1 : 0);
        }
        mplew.write(shop.getItemId() - 5030000);
        mplew.write(shop.getSize());
        mplew.write(shop.getMaxSize());
        if (shop.getShopType() != 1) {
            mplew.write(shop.isOpen() ? 0 : 1);
        }
    }

    public static void addCharacterInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.writeLong(-1L);
        mplew.write(new byte[19]);

        addCharStats(mplew, chr);

        mplew.write(chr.getBuddylist().getCapacity());   //最大好友数

        if (chr.getBlessOfFairyOrigin() != null) {      //如果角色的精灵的祝福技能不等于没有—新手加攻击技能
            mplew.write(1);
            mplew.writeMapleAsciiString(chr.getBlessOfFairyOrigin());
        } else {
            mplew.write(0);
        }

        if (chr.getBlessOfEmpressOrigin() != null) {      //如果角色的女皇的祝福技能不等于没有—新手加攻击技能
            mplew.write(1);
            mplew.writeMapleAsciiString(chr.getBlessOfEmpressOrigin());
        } else {
            mplew.write(0);
        }

        MapleQuestStatus ultExplorer = chr.getQuestNoAdd(MapleQuest.getInstance(111111));
        if ((ultExplorer != null) && (ultExplorer.getCustomData() != null)) {
            mplew.write(1);
            mplew.writeMapleAsciiString(ultExplorer.getCustomData());
        } else {
            mplew.write(0);
        }

        addInventoryInfo(mplew, chr);

        addSkillInfo(mplew, chr);

        mplew.writeShort(0);

        addCoolDownInfo(mplew, chr);

        addQuestInfo(mplew, chr);

        addRingInfo(mplew, chr); //8个OO

        addRocksInfo(mplew, chr);//连续发送FF C9 9A 3B 

        chr.QuestInfoPacket(mplew);

        if ((chr.getJob() >= 3300) && (chr.getJob() <= 3312)) {   //如果职业是豹子
            addJaguarInfo(mplew, chr);
        }


        mplew.writeShort(0);  //我加的
        mplew.writeShort(0);
        mplew.writeShort(0);
        //mplew.writeInt(chr.getAccountID());
       // mplew.writeInt(0);
       // mplew.writeInt(0);
        

        if (GameConstants.is神之子(chr.getJob())) {
            mplew.writeShort(-1);
            mplew.write(0);
            chr.getStat().神之子属性(mplew);
            mplew.write(0);
            mplew.writeInt(37623);
            mplew.writeInt(21290);
            chr.getStat().神之子属性(mplew);
            mplew.writeInt(0);
        }

        mplew.writeShort(0);
        mplew.writeShort(0);
        mplew.writeShort(0);
        if ((chr.getJob() >= 2400) && (chr.getJob() <= 2412)) {
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(10))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(11))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(12))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(13))).intValue());

            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(20))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(21))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(22))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(23))).intValue());

            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(30))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(31))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(32))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(40))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(41))).intValue());

            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(1))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(2))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(3))).intValue());
            mplew.writeInt(((Integer) chr.getphantomskills().get(Integer.valueOf(4))).intValue());
        } else {
            mplew.writeZeroBytes(66);
        }

        加载内在能力(mplew, chr);
        mplew.writeInt(chr.getRyLevel());
        mplew.writeInt(chr.getRyExp());
        mplew.writeLong(1L);
        mplew.writeLong(0L);
        mplew.writeLong(0L);
        mplew.write(0);

        mplew.writeLong(getTime(-2L));

        mplew.writeLong(0L);
        mplew.write(0);
        mplew.writeInt(0);
        mplew.writeShort(0);

        mplew.writeLong(getTime(-2L));

        mplew.writeInt(0);
        mplew.write(0);
        mplew.writeShort(1);
        mplew.writeInt(1);
        mplew.writeInt(0);//115改动
        mplew.writeInt(100);//115改动
        mplew.writeLong(getTime(-2L));

        mplew.writeInt(0);
        mplew.writeInt(0);//115++
        mplew.writeInt(0);//115++
        mplew.write(0);//115++
        //mplew.writeInt(DateUtil.getTime());
        mplew.writeInt(0);
        
        if (GameConstants.is神之子(chr.getJob())) {
            mplew.writeZeroBytes(12);
            mplew.writeInt(267871);
            mplew.writeInt(102);
            mplew.writeInt(2);
            mplew.writeInt(26);
            mplew.writeInt(4);
            mplew.writeInt(4);
            mplew.writeInt(4);
            mplew.writeInt(5);
            mplew.writeInt(5);
            mplew.writeInt(4);
            mplew.writeInt(2);
            mplew.writeInt(16);
            mplew.writeInt(7);
            mplew.writeInt(38);
        } else {
            mplew.writeZeroBytes(56);//118
        }

        long someExpireTime = getTime(System.currentTimeMillis() + 701913504L);
        mplew.writeLong(someExpireTime);
        mplew.write(0);//119+
        mplew.write(1);
    }

    public static void 加载内在能力(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        
        int 内在潜能个数 = 0;
        if (chr.getNz1() != 0) {
            内在潜能个数++;
        }
        if (chr.getNz2() != 0) {
            内在潜能个数++;
        }
        if (chr.getNz3() != 0) {
            内在潜能个数++;
        }
        if (chr.getNz1()==0){
            mplew.writeInt(0);
        }
        if (chr.getNz1() != 0) {
            //mplew.write(chr.getNz1W1());
            //mplew.write(chr.getNz1W2());
            mplew.writeShort(内在潜能个数);
            mplew.write(1);
            mplew.writeInt(chr.getNz1());
        }
        if (chr.getNz2() != 0) {
           // mplew.write(chr.getNz2W1());
            //mplew.write(chr.getNz2W2());
            mplew.writeShort(内在潜能个数);
            mplew.write(2);
            mplew.writeInt(chr.getNz2());
        }
        if (chr.getNz3() != 0) {
          //  mplew.write(chr.getNz3W1());
           // mplew.write(chr.getNz3W2());
            mplew.writeShort(内在潜能个数);
            mplew.write(3);
            mplew.writeInt(chr.getNz3());
        }
        if (chr.getNz1()!=0){
        mplew.writeInt(内在潜能个数++);
        }
    }

    public static void addMonsterBookInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.writeInt(0);
        if (chr.getMonsterBook().getSetScore() > 0) {
            chr.getMonsterBook().writeFinished(mplew);
        } else {
            chr.getMonsterBook().writeUnfinished(mplew);
        }
        mplew.writeInt(chr.getMonsterBook().getSet());
        mplew.writeZeroBytes(9);
    }

    public static void addCharacterphantomskills(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("select * from phantomskills where characterid=?");
            ps.setInt(1, chr.getId());
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                mplew.writeInt(rs.getInt("skill1_0"));
                mplew.writeInt(rs.getInt("skill1_1"));
                mplew.writeInt(rs.getInt("skill1_2"));
                mplew.writeInt(rs.getInt("skill1_3"));

                mplew.writeInt(rs.getInt("skill2_0"));
                mplew.writeInt(rs.getInt("skill2_1"));
                mplew.writeInt(rs.getInt("skill2_2"));
                mplew.writeInt(rs.getInt("skill2_3"));

                mplew.writeInt(rs.getInt("skill3_0"));
                mplew.writeInt(rs.getInt("skill3_1"));
                mplew.writeInt(rs.getInt("skill3_2"));

                mplew.writeInt(rs.getInt("skill4_0"));
                mplew.writeInt(rs.getInt("skill4_1"));

                mplew.writeInt(rs.getInt("skill1"));
                mplew.writeInt(rs.getInt("skill2"));
                mplew.writeInt(rs.getInt("skill3"));
                mplew.writeInt(rs.getInt("skill4"));
            }
            rs.close();
            ps.close();
        } catch (SQLException ex) {
        }
    }

    public static void addPetItemInfo(MaplePacketLittleEndianWriter mplew, Item item, MaplePet pet, boolean active) {
        if (item == null) {
            mplew.writeLong(getKoreanTimestamp((long) (System.currentTimeMillis() * 1.5)));
        } else {
            addExpirationTime(mplew, item.getExpiration() <= System.currentTimeMillis() ? -1L : item.getExpiration());
        }
        mplew.writeInt(-1);
        mplew.writeAsciiString(pet.getName(), 13);
        mplew.write(pet.getLevel());
        mplew.writeShort(pet.getCloseness());
        mplew.write(pet.getFullness());
        if (item == null) {
            mplew.writeLong(getKoreanTimestamp((long) (System.currentTimeMillis() * 1.5)));
        } else {
            addExpirationTime(mplew, item.getExpiration() <= System.currentTimeMillis() ? -1L : item.getExpiration());
        }
        mplew.writeShort(0);
        mplew.writeShort(pet.getFlags());
        mplew.writeInt((pet.getPetItemId() == 5000054) && (pet.getSecondsLeft() > 0) ? pet.getSecondsLeft() : 0);
        mplew.writeShort(0);
        mplew.write((byte) (active ? 0 : pet.getSummoned() ? pet.getSummonedValue() : 0));
        mplew.writeInt(active ? pet.getBuffSkill() : 0);
        mplew.writeInt(-1);
        mplew.writeInt(100);
        mplew.writeLong(0L);
        mplew.writeShort(0);
    }

    public static void addShopInfo(MaplePacketLittleEndianWriter mplew, MapleShop shop, MapleClient c) {
        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();

        mplew.write(0);
        mplew.writeInt(DateUtil.getTime());
        mplew.write(shop.getRanks().size() > 0 ? 1 : 0);
        if (shop.getRanks().size() > 0) {
            mplew.write(shop.getRanks().size());
            for (Pair s : shop.getRanks()) {
                mplew.writeInt(((Integer) s.left));
                mplew.writeMapleAsciiString((String) s.right);
            }
        }

        mplew.writeShort(shop.getItems().size() + c.getPlayer().getRebuy().size());
        for (MapleShopItem item : shop.getItems()) {
            addShopItemInfo(mplew, item, shop, ii, null);
        }
        for (Item i : c.getPlayer().getRebuy()) {
            addShopItemInfo(mplew, new MapleShopItem(i.getItemId(), (int) ii.getPrice(i.getItemId()), i.getQuantity()), shop, ii, i);
        }
    }

    public static void addShopItemInfo(MaplePacketLittleEndianWriter mplew, MapleShopItem item, MapleShop shop, MapleItemInformationProvider ii, Item i) {
     /*   mplew.writeLong(0L);
        mplew.writeInt(item.getItemId()); //物品ID
        mplew.writeInt(item.getPrice());  //物品价格
        mplew.write(0);  //折扣
        mplew.writeLong(0);
        mplew.writeInt(item.getReqItem());
        mplew.writeInt(item.getReqItemQ());
        mplew.writeInt(0);
        mplew.writeShort(0);
        mplew.writeInt(1440 * item.getPeriod());
        //mplew.writeInt(item.getRank());
        mplew.writeInt(0);

        mplew.writeLong(0);
        mplew.writeInt(0);
        mplew.writeLong(0);

        mplew.writeLong(getTime(-2L));
        mplew.writeLong(getTime(-1L));
        mplew.writeInt(0);  //种类
        mplew.writeMapleAsciiString("1900010100");
        mplew.writeMapleAsciiString("2079010100");
        mplew.write(item.getState() > 0 ? 1 : 0);
        mplew.writeInt(item.getPeriod() > 0 ? 1 : 0);
        mplew.writeInt(0);

        
        if ((!GameConstants.isThrowingStar(item.getItemId())) && (!GameConstants.isBullet(item.getItemId()))) {
            //mplew.writeShort(item.getQuantity()); //这是GMS的写法 购买一次物品的数量  有些物品是打包一起卖的
            mplew.writeShort(1);  //这是原本的写法 购买一次物品的数量  需要修改
            mplew.writeShort(item.getBuyable());
        } else {
            mplew.writeZeroBytes(6);
            mplew.writeShort(BitTools.doubleToShortBits(ii.getPrice(item.getItemId())));
            mplew.writeShort(ii.getSlotMax(item.getItemId()));
        }
        
        
        mplew.write(i == null ? 0 : 1);
        if (i != null) {
            addItemInfo(mplew, i, true, true);
        }
        if (shop.getRanks().size() > 0) {
            mplew.write(item.getRank() >= 0 ? 1 : 0);
            if (item.getRank() >= 0) {
                mplew.write(item.getRank());
            }
        }

        mplew.writeLong(0L);
        mplew.writeLong(0L);
        
        for (int x = 0; x < 4; x++) {
            mplew.writeLong(9410165 + x);
        }
        mplew.writeInt(9410198);
        mplew.writeInt(0);*/
        
        mplew.writeLong(0L);
        mplew.writeInt(item.getItemId()); //物品ID
        mplew.writeInt(item.getPrice());  //物品价格
        mplew.write(0);  //折扣
        //mplew.writeLong(0);
        mplew.writeInt(item.getReqItem());
        mplew.writeInt(item.getReqItemQ());
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(1440 * item.getPeriod());
        //mplew.writeInt(item.getRank());
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeInt(0);
        mplew.writeShort(0);

        mplew.writeLong(getTime(-2L));
        mplew.writeLong(getTime(-1L));
        mplew.writeInt(0);  //种类
        mplew.writeMapleAsciiString("1900010100");
        mplew.writeMapleAsciiString("2079010100");
        mplew.write(item.getState() > 0 ? 1 : 0);
        mplew.writeInt(item.getPeriod() > 0 ? 1 : 0);
        mplew.writeInt(0);

        
        if ((!GameConstants.isThrowingStar(item.getItemId())) && (!GameConstants.isBullet(item.getItemId()))) {
            //mplew.writeShort(item.getQuantity()); //这是GMS的写法 购买一次物品的数量  有些物品是打包一起卖的
            mplew.writeShort(1);  //这是原本的写法 购买一次物品的数量  需要修改
            mplew.writeShort(item.getBuyable());
        } else {
            mplew.writeZeroBytes(6);
            mplew.writeShort(BitTools.doubleToShortBits(ii.getPrice(item.getItemId())));
            mplew.writeShort(ii.getSlotMax(item.getItemId()));
        }
        
        
        mplew.write(i == null ? 0 : 1);
        if (i != null) {
            addItemInfo(mplew, i, true, true);
        }
        if (shop.getRanks().size() > 0) {
            mplew.write(item.getRank() >= 0 ? 1 : 0);
            if (item.getRank() >= 0) {
                mplew.write(item.getRank());
            }
        }

        mplew.writeLong(0L);
        mplew.writeLong(0L);
        
        for (int x = 0; x < 4; x++) {
            mplew.writeLong(9410165 + x);
        }
        mplew.writeInt(9410169);
        mplew.writeInt(0);
        
        /*
        mplew.writeLong(0L);
        mplew.writeInt(item.getItemId()); //物品ID
        mplew.writeInt(item.getPrice());  //物品价格
        mplew.write(0);  //折扣
        mplew.writeInt(item.getReqItem());
        mplew.writeInt(item.getReqItemQ());
        mplew.writeLong(0L);
        mplew.writeLong(1440 * item.getPeriod());
        
        mplew.writeInt(item.getRank());
        
        mplew.writeLong(0L); //117+
        mplew.writeInt(0);   //117+
        
        mplew.writeLong(getTime(-2L));
        mplew.writeLong(getTime(-1L));
        mplew.writeInt(0);  //种类
        mplew.writeMapleAsciiString("1900010100");
        mplew.writeMapleAsciiString("2079010100");
        mplew.write(0);
        mplew.write(item.getState() > 0 ? 1 : 0);
        mplew.writeInt(item.getPeriod() > 0 ? 1 : 0);
        
        if ((!GameConstants.isThrowingStar(item.getItemId())) && (!GameConstants.isBullet(item.getItemId()))) {
            //mplew.writeShort(item.getQuantity()); //这是GMS的写法 购买一次物品的数量  有些物品是打包一起卖的
            mplew.writeShort(1);  //这是原本的写法 购买一次物品的数量  需要修改
            mplew.writeShort(item.getBuyable());
        } else {
            mplew.writeZeroBytes(6);
            mplew.writeShort(BitTools.doubleToShortBits(ii.getPrice(item.getItemId())));
            mplew.writeShort(ii.getSlotMax(item.getItemId()));
        }
        
        
        mplew.write(i == null ? 0 : 1);
        if (i != null) {
            addItemInfo(mplew, i, true, true);
        }
        if (shop.getRanks().size() > 0) {
            mplew.write(item.getRank() >= 0 ? 1 : 0);
            if (item.getRank() >= 0) {
                mplew.write(item.getRank());
            }
        }

        mplew.writeLong(0L);
        mplew.writeLong(0L);
        
        for (int x = 0; x < 4; x++) {
            mplew.writeLong(9410165 + x);
        }
        mplew.writeLong(9410198);
        mplew.writeInt(0);*/
    }

    public static void addJaguarInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        mplew.write(chr.getIntNoRecord(111112));
        mplew.writeZeroBytes(20);
    }

    public static <E extends Buffstat> void writeSingleMask(MaplePacketLittleEndianWriter mplew, E statup) {
        //for (int i = GameConstants.MAX_BUFFSTAT; i >= 1; i--) {
        for (int i = 13; i >= 1; i--) {
            mplew.writeInt(i == statup.getPosition() ? statup.getValue() : 0);
        }
    }

    public static <E extends Buffstat> void writeMask(MaplePacketLittleEndianWriter mplew, Collection<E> statups) {
        //int[] mask = new int[GameConstants.MAX_BUFFSTAT];
        int[] mask = new int[13];
        for (Buffstat statup : statups) {
            mask[(statup.getPosition() - 1)] |= statup.getValue();
        }
        for (int i = mask.length; i >= 1; i--) {
            mplew.writeInt(mask[(i - 1)]);
        }
    }

    public static <E extends Buffstat> void writeBuffMask(MaplePacketLittleEndianWriter mplew, Collection<Pair<E, Integer>> statups) {
        //int[] mask = new int[GameConstants.MAX_BUFFSTAT];
        int[] mask = new int[13];
        for (Pair statup : statups) {
            mask[(((Buffstat) statup.left).getPosition() - 1)] |= ((Buffstat) statup.left).getValue();
        }
        for (int i = mask.length; i >= 1; i--) {
            mplew.writeInt(mask[(i - 1)]);
        }
    }

    public static <E extends Buffstat> void writeBuffMask(MaplePacketLittleEndianWriter mplew, Map<E, Integer> statups) {
        //int[] mask = new int[GameConstants.MAX_BUFFSTAT];
        int[] mask = new int[13];
        for (Buffstat statup : statups.keySet()) {
            mask[(statup.getPosition() - 1)] |= statup.getValue();
        }
        for (int i = mask.length; i >= 1; i--) {
            mplew.writeInt(mask[(i - 1)]);
        }
    }

    public static void addPartTimeJob(MaplePacketLittleEndianWriter mplew, PartTimeJob parttime) {
        mplew.write(parttime.getJob());
        if (parttime.getJob() > 0 && parttime.getJob() <= 5) {
            mplew.writeReversedLong(parttime.getTime());
        } else {
            mplew.writeReversedLong(-2L);
        }
        mplew.writeInt(parttime.getReward());
        mplew.write(parttime.getReward() > 0);
    }
}

/* Location:           C:\Users\文炳\Desktop\CXFBY\114Maplewing.jar
 * Qualified Name:     tools.packet.PacketHelper
 * JD-Core Version:    0.6.2
 */